/*
 * bomb.c
 *
 *  Created on: 5 mars 2013
 *      Author: User One
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <SDL.h>
#include <SDL_image.h>

#include "../include/game.h"
#include "../include/misc.h"


struct s_bomb {
	int x, y, power;
	Uint32 time;
	SDL_Surface * one_img[5];
	enum e_state current_state;
};



// Creates a new bomb in the x,y position
t_bomb bomb_set(int x, int y, int power){

	t_bomb bomb = malloc(sizeof(*bomb));


	if (!bomb)
		error("Memory error");

	bomb->one_img[0] = load_image(IMG_BOMB_TTL1);
	bomb->one_img[1] = load_image(IMG_BOMB_TTL2);
	bomb->one_img[2] = load_image(IMG_BOMB_TTL3);
	bomb->one_img[3] = load_image(IMG_BOMB_TTL4);
	bomb->one_img[4] = load_image(IMG_BOMB_TTL5);

	bomb->power = power;
	bomb->time = SDL_GetTicks(); // Get the time when the bomb is set
	bomb->x=x;
	bomb->y=y;

	bomb->current_state = time_4;

	return bomb;

}

//Sets the cell where the player is to a CELL_BOMB
void bomb_seton_map (t_player player, t_map map){
	int x = player_get_x(player);
	int y = player_get_y(player);
	map_set_cell_type(map, x, y, CELL_BOMB);
}

// Changes the state of the bomb
void bomb_state_set(t_bomb bomb, enum e_state state){
	assert(bomb);
	bomb->current_state = state;
}

// Returns the bomb's current position
int bomb_get_x(t_bomb bomb) {
	assert(bomb != NULL);
	return bomb->x;
}
int bomb_get_y(t_bomb bomb) {
	assert(bomb != NULL);
	return bomb->y;
}

// Returns the power of the bomb
int bomb_get_power(t_bomb bomb) {
	assert(bomb != NULL);
	return bomb->power;
}

// Checks if there is a case in the bomb's reach and exploads it diplaying a random bonus/malus
void bomb_expload_case(t_bomb bomb, t_map map) {
	int x = bomb_get_x(bomb);
	int y = bomb_get_y(bomb);
	int rang = bomb_get_power(bomb);

	t_compose_type  bonus[5] = {CELL_CASE_BOMBINC, CELL_CASE_BOMBDEC, CELL_CASE_RANGEINC, CELL_CASE_RANGEDEC, CELL_CASE_LIFE};

	int randNum1=0, i=0;

	srand(time(NULL));

	for (i=0;i<10;i++){
		randNum1 = 5 * (rand() / (RAND_MAX + 1.0));
	}

	int ji=1;

	while (ji <= rang && map_is_explosable(map, x+ji,y)) {
	if (map_is_inside(map,x+ji,y) && map_get_cell_type(map, x+ji, y) == CELL_CASE) {

		map_set_cell_type(map, x+ji, y, bonus[randNum1]);
		int subtype = map_get_cell_subtype(map,x+ji,y);
		int new_type = (subtype << 4) | CELL_BONUS ;
		map_set_cell_type(map, x+ji, y, new_type);
	}
	ji++;
	}
	ji=1;
	while (ji <= rang && map_is_explosable(map, x-ji,y)) {
	if (map_is_inside(map,x-ji,y) && map_get_cell_type(map, x-ji, y) == CELL_CASE) {

		map_set_cell_type(map, x-ji, y, bonus[randNum1]);
		int subtype = map_get_cell_subtype(map,x-ji,y);
		int new_type = (subtype << 4) | CELL_BONUS ;
		map_set_cell_type(map, x-ji, y, new_type);
	}
	ji++;
	}
	ji=1;
	while (ji <= rang && map_is_explosable(map, x,y+ji)) {
	if (map_is_inside(map,x,y+ji) && map_get_cell_type(map, x, y+ji) == CELL_CASE) {

		map_set_cell_type(map, x, y+ji, bonus[randNum1]);
		int subtype = map_get_cell_subtype(map,x,y+ji);
		int new_type = (subtype << 4) | CELL_BONUS ;
		map_set_cell_type(map, x, y+ji, new_type);
	}
	ji++;
	}
	ji=1;
	while (ji <= rang && map_is_explosable(map, x,y-ji)) {
	if (map_is_inside(map,x,y-ji) && map_get_cell_type(map, x, y-ji) == CELL_CASE) {
		map_set_cell_type(map, x, y-ji, bonus[randNum1]);
		int subtype = map_get_cell_subtype(map,x,y-ji);
		int new_type = (subtype << 4) | CELL_BONUS ;
		map_set_cell_type(map, x, y-ji, new_type);
	}
	ji++;
	}
	ji=1;
}

// Displays the fire around the bomb
void bomb_explosion_display (t_bomb bomb, SDL_Surface *screen, t_map map) {

	int ji=1, power=bomb_get_power(bomb);
	int x = bomb_get_x(bomb);
	int y = bomb_get_y(bomb);

	SDL_Rect ext_place[16];


	while (map_is_explosable(map, x+ji, bomb->y) && ji<power+1 ) {
		ext_place[ji-1].x=(x+ji) * SIZE_BLOC;
		ext_place[ji-1].y=(y) * SIZE_BLOC;
		ji++;
	}

	ji=1;

	while (map_is_explosable(map, x, y+ji) && ji<power+1) {
		ext_place[4+ji-1].x=(x) * SIZE_BLOC;
		ext_place[4+ji-1].y=(y+ji) * SIZE_BLOC;
		ji++;
	}

	ji=1;

	while (map_is_explosable(map, x-ji, y) && ji<power+1 ) {
		ext_place[8+ji-1].x=(x-ji) * SIZE_BLOC;
		ext_place[8+ji-1].y=(y) * SIZE_BLOC;
		ji++;
	}

	ji=1;

	while (map_is_explosable(map, x, y-ji) && ji<power+1 ) {
		ext_place[12+ji-1].x=(x) * SIZE_BLOC;
		ext_place[12+ji-1].y=(y-ji) * SIZE_BLOC;
		ji++;
	}

	ji=1;

	int i=0;
	for (i=0; i<15; i++){
		for (ji=1; ji<power+1; ji++){
			if (i==ji-1 && map_is_explosable(map, x+ji, y)){
				SDL_BlitSurface(bomb->one_img[bomb->current_state], NULL, screen,
						&ext_place[i]);
			}
		}
		for (ji=1; ji<power+1; ji++){
			if (i==4+ji-1 && map_is_explosable(map, x, y+ji)){
				SDL_BlitSurface(bomb->one_img[bomb->current_state], NULL, screen,
						&ext_place[i]);
			}
		}
		for (ji=1; ji<power+1; ji++){
			if (i==8+ji-1 && map_is_explosable(map, x-ji, y)){
				SDL_BlitSurface(bomb->one_img[bomb->current_state], NULL, screen,
						&ext_place[i]);
			}
		}
		for (ji=1; ji<power+1; ji++){
			if (i==12+ji-1 && map_is_explosable(map, x, y-ji)){
				SDL_BlitSurface(bomb->one_img[bomb->current_state], NULL, screen,
						&ext_place[i]);
			}
		}
	}

}

// Displays the bomb and it's explosion after 4 seconds
void bomb_display(t_bomb bomb, SDL_Surface *screen, t_map map) {
	assert(bomb);
	assert(screen);


	SDL_Rect place;
	place.x = bomb->x * SIZE_BLOC;
	place.y = bomb->y * SIZE_BLOC;

	SDL_BlitSurface(bomb->one_img[bomb->current_state], NULL, screen,
			&place);


	Uint32 diff = (SDL_GetTicks()-bomb->time);
	if(diff>1000){
		bomb_state_set(bomb, time_3);
	}
	Uint32 diff1 = (SDL_GetTicks()-bomb->time);
	if(diff1>2000){
		bomb_state_set(bomb, time_2);
	}

	Uint32 diff2 = (SDL_GetTicks()-bomb->time);
	if(diff2>3000){
		bomb_state_set(bomb, time_1);
	}
	Uint32 diff3 = (SDL_GetTicks()-bomb->time);
	if(diff3>4000){
		bomb_state_set(bomb, time_5);
		map_set_cell_type(map, bomb->x, bomb->y, CELL_BOMB);
		bomb_explosion_display(bomb, screen, map);
	}
	Uint32 diff4 = (SDL_GetTicks()-bomb->time);
	if(diff4> 4300){
		bomb->one_img[bomb->current_state]=0;
		map_set_cell_type(map, bomb->x, bomb->y, CELL_EMPTY);
		bomb_expload_case(bomb, map);
	}
}
